import React, { useEffect, useState, useRef } from 'react';
import { connect, Dispatch } from 'umi';
import _ from 'lodash';
import styles from './index.less';
import { useEffectOnce } from 'react-use';
import { ConnectProps, ConnectState } from '@/models/connect';
import { Button, Select, InputNumber, Space, Checkbox } from 'antd';
import { jsapi, viewUtils } from '@/utils/arcgis';
import { getUniqueValueInfos, getExtrudeSymbol } from './uniqueRender';
import ChartPart from './chartPart';
import { xor } from 'lodash';
import { useSelector, useDispatch } from 'umi';
import Right from './right';

export interface LineDesignCheckProps {}
const { Option } = Select;
const unitArr = [
  {
    value: 'kilometers',
    title: '千米',
  },
  {
    value: 'meters',
    title: '米',
  },
  {
    value: 'feet',
    title: '英尺',
  },
  {
    value: 'miles',
    title: '英里',
  },
  {
    value: 'nautical-miles',
    title: '海里',
  },
  {
    value: 'yards',
    title: '码数',
  },
];

// 冲区图层ID
const BUFFERLAYER = 'bufferLayer';
const BUILDINGLAYER_ID = 'buildings_demo';
const BUILDINGLAYER_KEY = 'osm_id';

const RENDER_CFG_LIST = [
  {
    value: '1',
    color: '#FEB151',
    label: '未拆迁',
  },
  {
    value: '2',
    color: '#FE6751',
    label: '未拆迁(延期)',
  },
  {
    value: '3',
    color: '#2FB0FF',
    label: '拆迁中',
  },
  {
    value: '4',
    color: '#3D98FF',
    label: '拆迁中（延期）',
  },
  {
    value: '5',
    color: '#3DFF9F',
    label: '已完成',
  },
  {
    value: '6',
    color: '#A5FB3F',
    label: '已完成（提前）',
  },
  {
    value: '7',
    color: '#EA3DFF',
    label: '已完成（延期）',
  },
];

const buildingRenderer = {
  type: 'unique-value', // autocasts as new SimpleRenderer()
  defaultSymbol: getExtrudeSymbol(),
  field: BUILDINGLAYER_KEY,
  uniqueValueInfos: getUniqueValueInfos(),
  visualVariables: [
    {
      type: 'size',
      field: 'Status',
      // valueUnit: 'meters',
      stops: [
        {
          // value: '2',
          size: 40,
        },
        // {
        //   value: '3',
        //   size: 100,
        // },
      ],
    },
  ],
};

const statusRenderer = {
  type: 'unique-value', // autocasts as new SimpleRenderer()
  defaultSymbol: getExtrudeSymbol(),
  field: 'Status',
  uniqueValueInfos: RENDER_CFG_LIST.map(({ value, color, label }) => {
    return {
      value,
      // label,
      symbol: getExtrudeSymbol(color),
    };
  }),
  visualVariables: [
    {
      type: 'size',
      field: 'Status',
      // valueUnit: 'meters',
      stops: [
        {
          size: 40,
        },
      ],
    },
  ],
};

const roadDemoCfg = {
  name: 'road_demo',
  url: 'https://portal.wccg.tech:9002/to443/server1/rest/services/Hosted/DesginRoadsDemo1/FeatureServer',
  elevationInfo: {
    mode: 'on-the-ground',
    offset: 4,
  },
  popupEnabled: true,
  objectIdField: 'objectid',
  outFields: ['*'],
  id: '202103RoadRedLine',
  title: '202103RoadRedLine',
  renderer: {
    type: 'simple', // autocasts as new SimpleRenderer()
    symbol: {
      type: 'line-3d', // autocasts as new LineSymbol3D()
      symbolLayers: [
        {
          type: 'line', // autocasts as new LineSymbol3DLayer()
          size: 3, // points
          material: { color: 'rgba(255, 0, 0, 1)' },
          cap: 'round',
          join: 'round',
        },
      ],
    },
  },
};

const buildingDemoCfg = {
  // renderer: buildingRenderer,
  renderer: statusRenderer,
  name: 'buildings_demo',
  title: 'buildings_demo',
  url: 'https://portal.wccg.tech:9002/to443/server1/rest/services/Hosted/buildings_demo/FeatureServer',
  elevationInfo: {
    mode: 'relative-to-scene',
  },
  popupEnabled: true,
  objectIdField: 'objectid',
  outFields: ['*'],
  id: BUILDINGLAYER_ID,
};

const LineDesignCheck: React.FC<LineDesignCheckProps> = () => {
  const dispatch = useDispatch();
  const curProjId = useSelector(store => store.app.curProjId);
  const curWorkingTab = useSelector(store => store.app.curWorkingTab);

  // 道路红线数据集
  const [lineList, setLineList] = useState([
    { title: '2021年03月道路红线设计数据', id: '202103RoadRedLine' },
  ]);
  const [bufferNum, setBufferNum] = useState(0); // 缓冲距离
  const [curLine, setCurLine] = useState<string | undefined>(undefined); // 当前选择红线数据ID
  const [unit, setUnit] = useState<string>('meters'); // 当前选择单位

  const [intersectResults, setIntersectResults] = useState<string[]>([]); // 碰撞结果列表
  const geometryEngine = useRef(null);
  const Graphic = useRef(null);
  const [isRenderRedLine, setIsRenderRedLine] = useState(false);
  const [renderCgfList, setRenderCgfList] = useState([1, 2, 3, 4, 5, 6, 7]); //未拆迁，拆迁中，已拆迁
  const preExpress = useRef('');
  const buildingsDemoLayerRef = useRef(null);
  const bufferLayerRef = useRef(null);
  const roadDemoLayerRef = useRef(null);

  useEffect(() => {
    if (!curProjId) {
      return;
    }
    addExtraLayer(dispatch, afterLayerAdd, curProjId);
  }, [curProjId]);

  useEffect(() => {
    if (buildingsDemoLayerRef.current) {
      buildingsDemoLayerRef.current.visible = true;
    }
    if (bufferLayerRef.current) {
      bufferLayerRef.current.visible = true;
    }
    if (roadDemoLayerRef.current) {
      roadDemoLayerRef.current.visible = true;
    }
    return () => {
      if (buildingsDemoLayerRef.current) {
        buildingsDemoLayerRef.current.visible = false;
      }
      if (bufferLayerRef.current) {
        bufferLayerRef.current.visible = false;
      }
      if (roadDemoLayerRef.current) {
        roadDemoLayerRef.current.visible = false;
      }
    };
  }, []);

  useEffect(() => {
    if (!curLine) {
      return;
    }
    updateBufferGraphic();
  }, [bufferNum, curLine, unit]);

  useEffect(() => {
    if (!buildingsDemoLayerRef.current) {
      return;
    }
    console.log(intersectResults);

    const newRenderer = _.cloneDeep(buildingRenderer);
    newRenderer.uniqueValueInfos = getUniqueValueInfos(intersectResults);
    // @ts-ignore
    buildingsDemoLayerRef.current.renderer = newRenderer;
    if (intersectResults.length) {
      setIsRenderRedLine(true);
    }
  }, [intersectResults]);

  useEffect(() => {
    if (!buildingsDemoLayerRef.current) {
      return;
    }

    if (!isRenderRedLine) {
      buildingsDemoLayerRef.current.renderer = statusRenderer;
    }
  }, [isRenderRedLine]);

  // 修改白膜显示和隐藏
  useEffect(() => {
    const _definitionExpression =
      renderCgfList.reduce((r, e, i) => {
        r += `'${e}',`;
        if (i === renderCgfList.length - 1) {
          r = r.slice(0, -1);
        }
        return r;
      }, 'Status in (') + ')';
    if (preExpress.current === _definitionExpression) {
      return;
    }

    if (buildingsDemoLayerRef.current) {
      buildingsDemoLayerRef.current.definitionExpression = _definitionExpression;
      preExpress.current = _definitionExpression;
    }
  }, [renderCgfList]);

  async function addExtraLayer(dispatch, afterLayerAdd, curProjId) {
    const [FeatureLayer, GraphicsLayer, geometryEngine_, Graphic_] = await jsapi.load([
      'esri/layers/FeatureLayer',
      'esri/layers/GraphicsLayer',
      'esri/geometry/geometryEngine',
      'esri/Graphic',
    ]);

    geometryEngine.current = geometryEngine_;
    Graphic.current = Graphic_;

    try {
      buildingDemoCfg.url = proj2ExtraLayer[curProjId].demoBuilding;
    } catch (error) {
      buildingDemoCfg.url = '';
    }

    let buildingsDemoLayer = new FeatureLayer(buildingDemoCfg);
    buildingsDemoLayerRef.current = buildingsDemoLayer;
    try {
      roadDemoCfg.url = proj2ExtraLayer[curProjId].roadDemo;
    } catch (error) {
      roadDemoCfg.url = '';
    }
    let roadDemoLayer = new FeatureLayer(roadDemoCfg);
    roadDemoLayerRef.current = roadDemoLayer;

    const bufferLayer = new GraphicsLayer({
      id: BUFFERLAYER,
      title: '缓冲区图层',
      elevationInfo: {
        mode: 'on-the-ground',
      },
    });
    bufferLayerRef.current = bufferLayer;
    const view = await viewUtils.isViewReady();
    view.map.addMany([buildingsDemoLayer, roadDemoLayer, bufferLayer]);

    console.log(roadDemoCfg.url, roadDemoLayer);
    // goto
    view.goTo(roadDemoLayer.camera);
  }

  // 更新缓冲区
  async function updateBufferGraphic() {
    const view = await viewUtils.isViewReady();
    if (view && geometryEngine.current && Graphic.current) {
      const bufferLayer = view.map.findLayerById(BUFFERLAYER);
      const roadLayer = view.map.findLayerById(curLine);
      if (bufferLayer && roadLayer) {
        bufferLayer.removeAll();
        // 找到道路数据的所有数据
        roadLayer.queryFeatures().then(result => {
          result.features.forEach(element => {
            let bufferGeometry: any =
              bufferNum !== 0
                ? (geometryEngine.current as any).geodesicBuffer(element.geometry, bufferNum, unit)
                : element.geometry;
            const graphic = new (Graphic.current as any)({
              geometry: bufferGeometry,
            });
            bufferLayer.add(graphic);
          });
        });
      }
    }
  }

  // 图层添加完成
  function afterLayerAdd(view, dispatch): void {
    // setLineList()
    // buildingListRef.current = []
  }

  // 检测线缓冲区与建筑底图的碰撞
  async function handleLineCheckClick() {
    const view = await viewUtils.isViewReady();
    console.log(111);
    if (geometryEngine.current) {
      const bufferLayer = view.map.findLayerById(BUFFERLAYER);
      const buildingLayer = view.map.findLayerById(BUILDINGLAYER_ID);
      if (!bufferLayer || !buildingLayer) {
        return;
      }
      console.log('----start check----');
      buildingLayer.queryFeatures().then(result => {
        const intersectBuildingArr: string[] = [];
        console.log(result.features);
        result.features.forEach(element => {
          bufferLayer.graphics.items.forEach(sonItem => {
            if ((geometryEngine.current as any).intersects(element.geometry, sonItem.geometry)) {
              intersectBuildingArr.push(element.attributes[BUILDINGLAYER_KEY] as string);
            }
          });
        });
        const _intersectResults = _.uniq(intersectBuildingArr);
        console.log(_intersectResults);
        setIntersectResults(_intersectResults);
      });
    }
  }

  function reset() {
    setIntersectResults([]);
    setIsRenderRedLine(false);
    setBufferNum(0);
    setCurLine(void 0);
  }

  function handleWhiteModelRender(item) {}

  function toggleVisibleBuilding(targetArr) {
    setRenderCgfList(pre => {
      return xor(pre, targetArr);
    });
  }

  return (
    <>
      <div className={styles.lineDesignCheck}>
        <ChartPart toggleVisibleBuilding={toggleVisibleBuilding} />
        <div className="side-panel2" style={{ position: 'absolute', top: 740, left: 24,zIndex:10 }}>
          <div className="side-panel2-title">设计检查</div>
          <div className="side-panel2-body" style={{ padding: 16 }}>
            <div className={styles.textDescription}>
              指定设计红线数据,设置缓冲距离,完成设计红线检查
            </div>
            <div>
              <Select
                value={curLine}
                style={{ width: '100%', marginBottom: '20px' }}
                onChange={value => {
                  setCurLine(value);
                }}
                placeholder={'请选择设计红线数据'}
              >
                {lineList.map(item => {
                  return (
                    <Option value={item.id} key={item.id}>
                      {item.title}
                    </Option>
                  );
                })}
              </Select>
            </div>
            <div className={styles.textKey}>缓冲距离设置：</div>
            <div>
              <InputNumber
                min={0}
                max={100000}
                value={bufferNum}
                precision={2}
                onChange={value => {
                  setBufferNum(value);
                }}
              />
              <Select
                value={unit}
                style={{ width: '72px', marginLeft: '8px' }}
                onChange={value => {
                  setUnit(value);
                }}
              >
                {unitArr.map(item => {
                  return (
                    <Option value={item.value} key={item.value}>
                      {item.title}
                    </Option>
                  );
                })}
              </Select>
            </div>
            <div className={styles.actionBtn}>
              <Button
                onClick={handleLineCheckClick}
                block
                className={'c-btn2'}
                type={'primary'}
                style={{ marginRight: 8 }}
              >
                检测
              </Button>
              {/* <Button onClick={() => {}} block type={'default'} style={{ marginRight: 8 }}>
              提交
            </Button> */}
              <Button className={'c-btn1'} onClick={reset} block type={'primary'}>
                还原
              </Button>
            </div>
          </div>
        </div>
      </div>
      <Right />
      1
    </>
  );
};

export default LineDesignCheck;
